package cn.wizzer.app.web.modules.controllers.user;

import cn.wizzer.app.crown.modules.models.enums.MatchTypeEnum;
import cn.wizzer.app.crown.modules.services.CrownMatchService;
import cn.wizzer.app.sys.modules.services.SysParamService;
import cn.wizzer.app.user.modules.models.LiveBroadcast;
import cn.wizzer.app.user.modules.models.vo.LiveInfo;
import cn.wizzer.app.user.modules.services.LiveBroadcastService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.web.commons.filter.ApiTokenFilter;
import cn.wizzer.app.web.commons.ulog.annotation.ULog;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.page.Pagination;
import cn.wizzer.framework.util.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.nutz.dao.Cnd;
import org.nutz.dao.util.cri.Static;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.adaptor.JsonAdaptor;
import org.nutz.mvc.annotation.*;

import static cn.wizzer.app.match.modules.models.constant.RedisKey.KEY_LIVE;

@Api("直播")
@IocBean
@At("/api/live/broad/cast")
public class ApiLiveBroadcastController {
    @Reference
    @Inject
    LiveBroadcastService liveBroadcastService;

    @Inject
    private PropertiesProxy conf;

    @Reference
    @Inject
    UserService userService;

    @Reference
    @Inject
    SysParamService sysParamService;

    @Inject
    RedisService redisService;

    @Reference
    @Inject
    private CrownMatchService crownMatchService;

    @ApiOperation("赛事")
    @At("/crown/match")
    @Ok("json")
    @Filters(@By(type = ApiTokenFilter.class))
    public Result match(Integer pageNo, Integer pageSize, MatchTypeEnum matchType, String keywords) {

        Cnd where = Cnd.where("stage", "in", "'FUTURE','BROWSE','RUNNING'");
        if (matchType != null) {
            where.and("type", "=", matchType);
        }
        if (matchType != null) {
            where.and(new Static("(league like concat('%','" + keywords + "','%') or mb_team like concat('%','" + keywords + "','%')  or tg_team like concat('%','" + keywords + "','%') )"));
        }
        Pagination pagination = crownMatchService.listPage(pageNo, pageSize, where.orderBy("league", "desc").orderBy("date_time", "asc"));
        return Result.success(pagination);
    }


    /**
     * @param code
     * @return
     * @description 获取直播列表
     */
    @At("/getLiveList")
    @Ok("json:full")
    public Result getLiveList(@Param("code") String code) {
        return liveBroadcastService.getLiveList(code);
    }

    /**
     * @description 搜索直播数据
     */
    @At
    @Ok("json:full")
    public Result query(String keyword, int pageNo, int pageSize) {
        return Result.success(liveBroadcastService.search(keyword, pageNo, pageSize));
    }

    /**
     * @param id
     * @return
     * @description 获取直播数据
     */
    @At("/getLive")
    @Ok("json:full")
    public Result getLive(@Param("id") String id) {
        return liveBroadcastService.getLive(id);
    }

    /**
     * @param code
     * @return
     * @description 获取直播数据
     */
    @At("/getLiveByCode")
    @Ok("json:full")
    public Result getLiveByCode(@ApiParam(required = true) @Param("code") String code) {
        return liveBroadcastService.getLiveByCode(code);
    }

    /**
     * @param liveNo
     * @param format
     */
    @At("/cover")
    @Ok("void")
    public void cover(@Param("liveNo") String liveNo, @Param("format") String format) {
        liveBroadcastService.cover(liveNo, format);
    }

    @At("/liveMember")
    @Ok("json:full")
    public Object liveMember(@ApiParam(name = "id") @Param("id") String id) {
        return Result.success(liveBroadcastService.liveMember(id));
    }

    @At("/myLive")
    @Ok("json:full")
    public Result myLive(@ApiParam(name = "videoId") @Param("videoId") String videoId, @Param("pageNo") Integer pageNo, @Param("pageSize") Integer pageSize) {
        String appid = Mvcs.getReq().getHeader("appid");
        return liveBroadcastService.myLive(videoId, appid, pageNo, pageSize);
    }

    @At("/preStart")
    @Ok("json:full")
    @Filters({@By(type = ApiTokenFilter.class)})
    public Result preStart(
            @Param("videoId") String videoId,
            @ApiParam(required = true) @Param("categoryId") String categoryId) {
        String appid = Mvcs.getReq().getHeader("appid");
        String liveKey = appid + "-" + (Strings.isNotBlank(videoId) ? videoId : categoryId);
        return Result.success(new NutMap()
                .putv("pushUrl", sysParamService.fetch().getPushVideoStreamUrl())
                .putv("param", liveKey + "?key=" + appid)
        );
    }

    /**
     * @date: 2019/12/12 16:24
     * @description
     */
    @At("/start")
    @Ok("json:full")
    @Filters(@By(type = ApiTokenFilter.class))
    @ULog(tag = "主播开始直播", msg = "直播间: ${videoId}, 标题: ${title}")
    public Result start(@Param("videoId") String videoId,
                        @Param("notice") String notice,
                        @Param("matchId") String matchId,
                        @Param("imgUri") String imgUri,
                        @ApiParam(required = true) @Param("categoryId") String categoryId, String title) {
        String appid = Mvcs.getReq().getHeader("appid");
        return liveBroadcastService.start(matchId, videoId, appid, notice, title, imgUri, categoryId);
    }

    @At("/start/notify")
    @AdaptBy(type = JsonAdaptor.class)
    public void startNotify(@Param("name") String streamId, @Param("key") String key) {
        Mvcs.getResp().setStatus(500);
        LiveInfo liveInfo = JSONUtil.parseStringToJavaBean(LiveInfo.class, redisService.hget(KEY_LIVE, streamId));
        if (liveInfo.getUserId().equals(key)) {
            liveBroadcastService.unRemoveLive(streamId);
            liveBroadcastService.refreshLive();
            Mvcs.getResp().setStatus(200);
        }
    }

    @At("/end")
    @Ok("json:full")
    public Result end() {
        String appid = Mvcs.getReq().getHeader("appid");
        return liveBroadcastService.end(appid);
    }

    @At("/end/notify")
    @AdaptBy(type = JsonAdaptor.class)
    public void endNotify(@Param("name") String streamId, @Param("key") String key) {
        LiveInfo liveInfo = JSONUtil.parseStringToJavaBean(LiveInfo.class, redisService.hget(KEY_LIVE, streamId));
        if (liveInfo.getUserId().equals(key)) {
            liveBroadcastService.removeLive(streamId);
        }
    }

    /**
     * 是否在直播
     *
     * @return Result
     */
    @At("/isOnLive")
    @Ok("json")
    @RequiresUser
    public Result isOnLive() {
        String appid = Mvcs.getReq().getHeader("appid");
        // 查询最新的一条直播记录,判断状态.
        LiveBroadcast fetch = liveBroadcastService.fetch(Cnd.where("userId", "=", appid).desc("opAt"));

        if (null != fetch && fetch.isState()) {
            String liveKey = appid + "-" + (Strings.isNotBlank(fetch.getVideoId()) ? fetch.getVideoId() : fetch.getCategoryId());
            return Result.success(new NutMap()
                    .putv("pushUrl", sysParamService.fetch().getPushVideoStreamUrl())
                    .putv("param", liveKey + "?key=" + appid)
            );
        }

        return Result.success("没有该用户直播记录");
    }

}
